home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / unarced / utilities / system / intuition / shadow / examples / swri / output.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-17  |  14.4 KB  |  523 lines

  1. /*
  2.  * SWRI Display Program.
  3.  *
  4.  * © Copyright 1991, ALl Rights Reserved
  5.  *
  6.  * David C. Navas
  7.  */
  8. #include <shadow/semaphore.h>
  9. #include "control.h"
  10. #include "/Gui/gui.h"
  11.  
  12. #include <ipc.h>
  13. #include <shadow/shadow_proto.h>
  14. #include <shadow/shadow_pragmas.h>
  15. #include <dos/dostags.h>
  16.  
  17. #include <math.h>
  18. #include <stdio.h>
  19.  
  20. #include <graphics/gfxmacros.h>
  21. #include <proto/graphics.h>
  22.  
  23. extern struct ExecBase * __far SysBase;
  24. struct IPCBase * __far IPCBase;
  25. struct ShadowBase * __far ShadowBase;
  26. struct DosLibrary * __far DOSBase;
  27. struct GfxBase * __far GfxBase;
  28.  
  29. struct Task * __far programTask;
  30. #define PROGRAMNAME "SWRINDE Output"
  31.  
  32. /*
  33.  * The number of windows we have open.
  34.  */
  35. ULONG __far GlobalNumOpen = 0;
  36. /*
  37.  * the global window tree, which holds all the windows
  38.  * interested in getting updated visuals.
  39.  */
  40. AVLTREE __far OutputClassTree = NULL;
  41.  
  42. /*
  43.  * ==========================================================================
  44.  * =                                                                        =
  45.  * =            Class definition for our Window Class.                      =
  46.  * =                                                                        =
  47.  * ==========================================================================
  48.  */
  49.  
  50. #define MYLOCALOUTPUTWINDOW "Output Window Class"
  51.  
  52. /*
  53.  * Attributes for our window class.
  54.  */
  55. #define MYPATCHES "Patch me up for ouput!"
  56. struct MyLocals {
  57.    double             ml_dispInfo[256];
  58. };
  59. ATTRIBUTE_TAG OWinAttrs[] =
  60.                         {
  61.                            {
  62.                               MYPATCHES,
  63.                               sizeof(struct MyLocals),
  64.                               NULL
  65.                            },
  66.                            TAG_END
  67.                         };
  68.  
  69. /*
  70.  * The Method References structures for our window class.
  71.  */
  72. extern METHOD_REF REF_OWinInitMethod[];
  73.  
  74. /*
  75.  * Methods for your window class.
  76.  */
  77. void OWinRemoveMethod(METHOD_ARGS),
  78.      __saveds OWinRefreshMethod(METHOD_ARGS);
  79. BOOL OWinInitMethod(METHOD_ARGS, CLUSTER cluster);
  80.  
  81. METHOD_TAG OWinMethods[] =
  82.                         {
  83.                            {
  84.                               METHOD_META_REMOVE,
  85.                               NULL, NULL,
  86.                               SHADOW_MSG_SYNC,
  87.                               METHOD_FLAG_PROC, 0,
  88.                               (METHODFUNCTYPE)OWinRemoveMethod, NULL
  89.                            },
  90.                            {
  91.                               METHOD_META_INIT,
  92.                               NULL, NULL,
  93.                               SHADOW_MSG_SYNC,
  94.                               METHOD_FLAG_PROC, 0,
  95.                               (METHODFUNCTYPE)OWinInitMethod,
  96.                                  REF_OWinInitMethod
  97.                            },
  98.                            {
  99.                               METHOD_WINDOW_REFRESH,
  100.                               NULL, NULL,
  101.                               SHADOW_MSG_CALL,
  102.                               METHOD_FLAG_PROC, 0,
  103.                               (METHODFUNCTYPE)OWinRefreshMethod, NULL
  104.                            },
  105.                            TAG_END
  106.                         };
  107.  
  108. /*
  109.  * Two patches that we make.
  110.  */
  111. /*
  112.  * First, the method description that patches the control window Close
  113.  *  method, so that we can exit our program when the control window goes
  114.  *  away.
  115.  */
  116. void OWinBreakMethod(METHOD_ARGS);
  117. METHOD_TAG OWinBreak =
  118.                         {
  119.                            METHOD_META_REMOVE,
  120.                            NULL, NULL,
  121.                            SHADOW_MSG_SYNC,
  122.                            METHOD_FLAG_PROC, 1,
  123.                            (METHODFUNCTYPE)OWinBreakMethod, NULL
  124.                         };
  125. /*
  126.  * Second, the method description that patches the control method
  127.  *  that is called when new infomation is presented to the system.
  128.  */
  129. void OWinPatchMethod(METHOD_ARGS);
  130. METHOD_TAG OWinPatch =
  131.                         {
  132.                            METHOD_SWRINDECONTROLCLUSTER_COMPUTE,
  133.                            NULL, NULL,
  134.                            SHADOW_MSG_CALL,
  135.                            METHOD_FLAG_PROC, -3000,
  136.                            (METHODFUNCTYPE)OWinPatchMethod, NULL
  137.                         };
  138.  
  139. int CXBRK(void)
  140. {
  141.    return(0);
  142. }
  143.  
  144. chkabort(void)
  145. {
  146.    return(0);
  147. }
  148.  
  149. void loadControl(CLUSTER cluster);
  150.  
  151. void main(void)
  152. {
  153.    CLUSTER controlCluster;
  154.  
  155.    programTask = FindTask(NULL);
  156.  
  157.    if (GfxBase = OpenLibrary("graphics.library", 0))
  158.    {
  159.       if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))
  160.       {
  161.          if (IPCBase = OpenLibrary("ppipc.library", 0))
  162.          {
  163.             if (ShadowBase = (struct ShadowBase *)
  164.                               OpenLibrary("shadow.library", 4))
  165.             {
  166.                if (controlCluster = FindJazzCluster(SWRINDE_CONTROL_CLUSTER))
  167.                {
  168.                   if (InitOOProgram(PROGRAMNAME))
  169.                   {
  170.                      loadControl(controlCluster);
  171.  
  172.                      RemoveCurrentProgram(NULL);
  173.                   } else
  174.                   {
  175.                      VPrintf("Coult not init your program\n", NULL);
  176.                   }
  177.  
  178.                   DropObject(controlCluster);
  179.  
  180.                } else
  181.                   VPrintf("Hey -- you need to run the control program first!\n", NULL);
  182.  
  183.                CloseLibrary(ShadowBase);
  184.             }
  185.             else
  186.                VPrintf("requires shadow.library V4.3 in libs:\n", NULL);
  187.  
  188.             CloseLibrary(IPCBase);
  189.          }
  190.          else
  191.             VPrintf("requires ppipc.library in libs:\n", NULL);
  192.       }
  193.       else
  194.       {
  195.          DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
  196.          Write(Output(), "Sorry, use 2.0\n", 15);
  197.       }
  198.  
  199.       CloseLibrary(DOSBase);
  200.       CloseLibrary(GfxBase);
  201.    }
  202. }
  203.  
  204. /*
  205.  * This function is used as a callback to RecurseBinTree.
  206.  * Used in order to change all the data in all of the output
  207.  * windows.
  208.  */
  209. void __regargs *UpdateAndRefresh(OBJECT window,
  210.                                  ULONG  key,
  211.                                  double *data)
  212. {
  213.    int i;
  214.    double *table;
  215.    struct RastPort *rp;
  216.    struct WindowObject *wo;
  217.    WORD top, left;
  218.  
  219.    table = FindAttribute(window, MYPATCHES);
  220.    wo    = FindAttribute(window, ATTR_WINDOW);
  221.  
  222.    if (!wo->wo_window || !table)
  223.    {
  224.       return NULL;
  225.    }
  226.  
  227.    rp   = wo->wo_window->RPort;
  228.    left = wo->wo_window->BorderLeft;
  229.    top  = wo->wo_window->BorderTop;
  230.  
  231.    /*
  232.     * Clear window.
  233.     */
  234.    SetWrMsk(rp, 1);
  235.    SetAPen(rp, 0);
  236.    RectFill(rp, 2 + left, 2 + top, 258 + left, 102 + top);
  237.    SetWrMsk(rp, -1);
  238.  
  239.    for(i = 0; i <256; i++)
  240.    {
  241.       table[i] = data[i];
  242.    }
  243.  
  244.    /*
  245.     * Redraw window.
  246.     */
  247.    DoJazzMethod(window, NULL, METHOD_WINDOW_REFRESH, METHOD_END);
  248.  
  249.    return NULL;
  250. }
  251.  
  252. void loadControl(CLUSTER cluster)
  253. {
  254.    CLASS    guiProcClass;
  255.    OBJECT   guiProcObject;
  256.    int      success;
  257.  
  258.    /*
  259.     * Make sure we only have one of these programs open at a time.
  260.     */
  261.    PSemString(PROGRAMNAME, SHADOW_EXCLUSIVE_SEMAPHORE);
  262.  
  263.    /*
  264.     * Is this program already running?
  265.     */
  266.    if (CreateInstance(NULL, MYLOCALOUTPUTWINDOW, METACLASS,
  267.                             cluster, METHOD_END))
  268.    {
  269.       VSemString(PROGRAMNAME);
  270.       return;
  271.    }
  272.  
  273.    /*
  274.     * No output, so startup all our classes
  275.     */
  276.    guiProcClass = FindJazzClass(GUIPROCESSCLASS);
  277.    guiProcObject = FindStringInWatchedBinTree((W_AVLTREE)
  278.                                 FindAttribute(guiProcClass, ATTR_OBJECTLIST),
  279.                                 GUITASK);
  280.    SetupMethodTags(OWinMethods, guiProcObject, (void *)-1);
  281.  
  282.    /*
  283.     * Can't use SetupMethodTags() for these patches because the
  284.     *  MethodTag is not NULL terminated.
  285.     * So setup our patches directly.
  286.     */
  287.    OWinBreak.mtag_procObject = OWinMethods->mtag_procObject;
  288.    OWinBreak.mtag_defnObject = OWinMethods->mtag_defnObject;
  289.  
  290.    OWinPatch.mtag_procObject = OWinMethods->mtag_procObject;
  291.    OWinPatch.mtag_defnObject = OWinMethods->mtag_defnObject;
  292.  
  293.    DropObject(guiProcClass);
  294.    DropObject(guiProcObject);
  295.  
  296.    /*
  297.     * We want the class to disappear FIRST, before anything else.
  298.     *  So we use the highest priority we have, which is 1.
  299.     * owinClass is TRANSFERRED to the program's resource tree.
  300.     */
  301.    success = AddAutoResource(NULL,
  302.                              CreateSubClass(NULL, WINDOWCLASS, METACLASS,
  303.                                             MYLOCALOUTPUTWINDOW,
  304.                                             NULL,
  305.                                             OWinAttrs,
  306.                                             OWinMethods,
  307.                                             METHOD_END),
  308.                              (char *)1);
  309.  
  310.    /*
  311.     * Class is defined - program has successfully started.
  312.     */
  313.    VSemString(PROGRAMNAME);
  314.  
  315.    /*
  316.     * startup our window.
  317.     */
  318.    success &= (int)CreateInstance(NULL, MYLOCALOUTPUTWINDOW, METACLASS,
  319.                                         cluster, METHOD_END);
  320.  
  321.    {
  322.       META        ctrlWindowClass;
  323.       W_AVLTREE   wbt;
  324.  
  325.       ctrlWindowClass = FindJazzClass(CONTROLWINCLASS);
  326.  
  327.       /*
  328.        * Add Patches.  Patches must disappear before the windows,
  329.        *  so we add them at a high priority (2).  Remember that Resources
  330.        *  in AVLTree ordering have high priorities in low numbers and
  331.        *  vice-versa
  332.        */
  333.  
  334.       /*
  335.        * Patch control window, so that we get notified when the control window
  336.        *  goes away.
  337.        */
  338.  
  339.       success &= AddAutoResource(NULL,
  340.                                  CreateInstance(NULL, PATCHERCLASS, METACLASS,
  341.                                                 &OWinBreak,
  342.                                                 ctrlWindowClass,
  343.                                                 METHOD_END),
  344.                                  (char *)2);
  345.  
  346.  
  347.       /*
  348.        * Oops, was the window already away?
  349.        */
  350.       if (wbt = FindAttribute(ctrlWindowClass, ATTR_OBJECTLIST))
  351.       {
  352.          if (!wbt->wv_value)
  353.             success = FALSE;
  354.       } else
  355.          success = FALSE;
  356.  
  357.       /*
  358.        * The actual output patch -- notification when new
  359.        *  information is presented to the system.
  360.        */
  361.       success &= AddAutoResource(NULL,
  362.                                  CreateInstance(NULL, PATCHERCLASS, METACLASS,
  363.                                                 &OWinPatch,
  364.                                                 cluster,
  365.                                                 METHOD_END),
  366.                                  (char *)2);
  367.  
  368.       DropObject(ctrlWindowClass);
  369.    }
  370.  
  371.    if (success)
  372.       HandleMessages(programTask);
  373. }
  374.  
  375. /*
  376.  * OWin Class methods.
  377.  */
  378. METHOD_REF  REF_OWinInitMethod[] = {
  379.                                        {
  380.                                           'JOBJ',
  381.                                           sizeof(void *),
  382.                                           SHADOW_CLUSTER
  383.                                        },
  384.                                        {
  385.                                           TAG_END,
  386.                                           0,
  387.                                           0
  388.                                        }
  389.                                     };
  390. BOOL OWinInitMethod(METHOD_ARGS, CLUSTER cluster)
  391. {
  392.    struct TagItem tag[10];
  393.  
  394.    tag[0].ti_Tag = WA_InnerWidth;
  395.    tag[0].ti_Data = 261;
  396.    tag[1].ti_Tag = WA_InnerHeight;
  397.    tag[1].ti_Data = 105;
  398.    tag[2].ti_Tag = WA_MinWidth;
  399.    tag[2].ti_Data = 60;
  400.    tag[3].ti_Tag = WA_MinHeight;
  401.    tag[3].ti_Data = 40;
  402.    tag[4].ti_Tag = WA_MaxWidth;
  403.    tag[4].ti_Data = -1;
  404.    tag[5].ti_Tag = WA_MaxHeight;
  405.    tag[5].ti_Data = -1;
  406.    tag[6].ti_Tag = WA_SimpleRefresh;
  407.    tag[6].ti_Data = TRUE;
  408.    tag[7].ti_Tag = WA_Left;
  409.    tag[7].ti_Data = 250 + GlobalNumOpen * 14;
  410.    tag[8].ti_Tag = WA_Top;
  411.    tag[8].ti_Data = GlobalNumOpen * 10;
  412.    tag[9].ti_Tag = TAG_END;
  413.  
  414.    object = DoJazzMethod(object, class->meta_superClass, METHOD_META_INIT,
  415.                                            NULL,
  416.                                            "Original Data Window",
  417.                                            NULL,
  418.                                            NULL,
  419.                                            tag, METHOD_END);
  420.  
  421.    DoJazzMethod(object, NULL, METHOD_WINDOW_REFRESH, METHOD_END);
  422.  
  423.    /*
  424.     * Add the window to the program's Resource tree.
  425.     * Add the window to the REFRESH tree.
  426.     * change the GlobalNumOpen count.
  427.     */
  428.    if (object && AddAutoResource(programTask->tc_UserData, object, NULL)
  429.        && AddNodeBinTree(&OutputClassTree, object, (ULONG)object))
  430.    {
  431.       GlobalNumOpen++;
  432.       return TRUE;
  433.    }
  434.    return FALSE;
  435. }
  436.  
  437. /*
  438.  * Remove the window from the Program's Resource tree.
  439.  * Remove it from the REFRESH window list.
  440.  * Then Close the window.
  441.  *
  442.  * if there are no more window's Open (GlobalNumOpen), kill the program
  443.  */
  444. void OWinRemoveMethod(METHOD_ARGS)
  445. {
  446.    DropObject(RemoveAutoResource(programTask->tc_UserData, object, NULL));
  447.    RemoveBinNode(&OutputClassTree, object, (ULONG)object);
  448.  
  449.    CallSuper();               /* Let GadTools know to get rid of gadgets. */
  450.    if (!--GlobalNumOpen)
  451.       Signal(programTask, SIGBREAKF_CTRL_C);
  452. }
  453.  
  454. /*
  455.  * When the control window is closed, kill this program.
  456.  */
  457. void OWinBreakMethod(METHOD_ARGS)
  458. {
  459.    Signal(programTask, SIGBREAKF_CTRL_C);
  460. }
  461.  
  462. /*
  463.  * Refresh the window with the new data.
  464.  */
  465. void __saveds OWinRefreshMethod(METHOD_ARGS)
  466. {
  467.    struct WindowObject *wo;
  468.    double *table;
  469.    int i;
  470.    struct RastPort *rp;
  471.    WORD top, left;
  472.    WORD poly[510];
  473.  
  474.    table = FindAttribute(object, MYPATCHES);
  475.    wo = FindAttribute(object, ATTR_WINDOW);
  476.  
  477.    if (!wo->wo_window || !table)
  478.    {
  479.       CallSuper();
  480.       return;
  481.    }
  482.  
  483.    Move(rp = wo->wo_window->RPort, 2 + (left = wo->wo_window->BorderLeft),
  484.                                    102 + (top = wo->wo_window->BorderTop) -
  485.                              (long)max(0.0, min(100.0, table[0] * 100.0)));
  486.  
  487.    SetAPen(rp, 1);
  488.    SetWrMsk(rp, 1);
  489.    for(i = 0; i < 255; i++)
  490.    {
  491.       poly[i * 2] = 3 + left + i;
  492.       poly[i * 2 + 1] = top + 102 -
  493.                               (long)max(0.0, min(100.0, table[i + 1] * 100.0));
  494.    }
  495.    PolyDraw(rp, 255, poly);
  496.    SetWrMsk(rp, -1);
  497.  
  498.    CallSuper();
  499. }
  500.  
  501. /*
  502.  * Everytime a new bunch of data comes through the patch-chain, this
  503.  *  method is called.
  504.  */
  505. void OWinPatchMethod(METHOD_ARGS)
  506. {
  507.    OBJECT compObject;
  508.  
  509. /*
  510.  * Get the original data
  511.  */
  512.    compObject = FindStringInBinTree(&((COMPOSITE)object)->cc_classes,
  513.                                 SWRINDE_DATA_CLASS);
  514.  
  515.    if (!compObject)
  516.       return;
  517.  
  518.    DoPreOrderBinTree(&OutputClassTree,
  519.                      UpdateAndRefresh,
  520.                      FindAttribute(compObject, ATTR_SWRINDE_DATA));
  521.    DropObject(compObject);
  522. }
  523.